package qx.hyj.petrescue.controller;


import cn.hutool.json.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import qx.hyj.petrescue.VO.BlogVo;
import qx.hyj.petrescue.VO.CommentVo;
import qx.hyj.petrescue.VO.JsonResult;
import qx.hyj.petrescue.constens.ErrorCode;
import qx.hyj.petrescue.dto.BlogAdd;
import qx.hyj.petrescue.dto.BlogType;
import qx.hyj.petrescue.dto.CommentAdd;
import qx.hyj.petrescue.entity.Blog;
import qx.hyj.petrescue.entity.Comment;
import qx.hyj.petrescue.exception.DescribeException;
import qx.hyj.petrescue.service.BlogService;


import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@RestController
@RequestMapping("/Petrescue/blog")
@Tag(name = "博客模块", description = "博客模块")
public class BlogController {

    @Resource
    private BlogService blogService;

    @Autowired
    private ServletContext servletContext;

    @PostMapping("/Blogs")
    @Operation(summary = "博客列表")
    public JsonResult<JSONObject> Blogs(@RequestBody BlogType blogType) {
        JSONObject loginResponse = new JSONObject();
        List<BlogVo> blogs = blogService.Blogs(blogType);
        if (blogs != null) {
            loginResponse.put("blogs", blogs);
            return new JsonResult<>(loginResponse);
        } else {
            return new JsonResult<>(null, ErrorCode.BLOG_AHOW_FAIL);
        }
    }

    @PostMapping("/addBlog")
    @Operation(summary = "添加博客")
    @Transactional(rollbackFor = Exception.class) // 添加事务管理
    public JsonResult<Map<String, Integer>> addBlog(
            @Parameter(description = "图片", example = "xxx.jpg")
            @RequestParam MultipartFile picture,
            @Parameter(description = "博客标题")
            @RequestParam String title,
            @Parameter(description = "博客内容")
            @RequestParam String content,
            @Parameter(description = "博客动物类型（1狗，2猫，3其他）")
            @RequestParam Integer dwType,
            @Parameter(description = "博客类型（1,2,3）")
            @RequestParam Integer blogType,
          HttpServletRequest request) {

        // 1. 检查文件是否为空
        if (picture == null || picture.isEmpty()) {
            return new JsonResult<>(null, ErrorCode.FILE_EMPTY);
        }

        try {
            Integer userId = (Integer) request.getAttribute("id");
            String originalFilename = picture.getOriginalFilename();

            // 2. 验证文件扩展名
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            if (!isValidExtension(extension)) {
                return new JsonResult<>(null, ErrorCode.INVALID_FILE_TYPE);
            }
            // 3. 生成安全文件名
            String fileName = generateSafeFilename(extension);

            // 4. 创建博客对象
            Blog blog = new Blog();
            blog.setTitle(title);
            blog.setContent(content);
            blog.setDwtype(dwType);
            blog.setBlogtype(blogType);
            blog.setAuthor(userId);
            // 获取项目根目录
            String projectRoot = System.getProperty("user.dir");

            String xdUrl;
            String relativePath;
           // 5. 确定存储路径
            switch (blog.getDwtype()) {
                case 1:
                    relativePath = projectRoot + File.separator + "images" + File.separator + "dog";
                    xdUrl = "http://localhost:8080/images/dog/"+ fileName;
                    break;
                case 2:
                    relativePath = projectRoot + File.separator + "images" + File.separator + "cat";
                    xdUrl = "http://localhost:8080/images/cat/"+ fileName;
                    break;
                case 3:
                    relativePath = projectRoot + File.separator + "images" + File.separator + "other";
                    xdUrl ="http://localhost:8080/images/other/"+  fileName;
                    break;
                default:
                    throw new IllegalArgumentException("Invalid dwtype");
            }

            // 6. 创建存储目录
            Path uploadPath = Paths.get(relativePath);
            // 创建目录（如果不存在）
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            // 7. 保存文件（含路径安全检查）
            Path filePath = uploadPath.resolve(fileName).normalize();
            if (!filePath.startsWith(uploadPath)) {
                return new JsonResult<>(null, ErrorCode.INVALID_FILE_PATH);
            }
            picture.transferTo(filePath);
            String absolutePath = filePath.toAbsolutePath().toString();
            // 8. 设置图片路径（使用系统分隔符）
            blog.setPicture(xdUrl);

            // 9. 保存博客记录
            Integer blogId = blogService.addBlog(blog);
            if (blogId == null) {
                throw new DescribeException("Failed to save blog"); // 触发事务回滚
            }

            // 10. 返回创建成功的ID
            return new JsonResult<>(Map.of("id", blogId));
        } catch (IOException e) {
            throw new RuntimeException("File upload failed", e); // 触发事务回滚
        } catch (Exception e) {
            return new JsonResult<>(null, ErrorCode.BLOG_ADD_FAIL);
        }
    }

    // 安全文件名生成
    private String generateSafeFilename(String extension) {
        return UUID.randomUUID().toString() +
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("_yyyyMMdd_HHmmss")) +
                extension;
    }

    // 文件类型验证
    private boolean isValidExtension(String ext) {
        Set<String> allowed = Set.of(".jpg", ".jpeg", ".png", ".gif", ".webp");
        return allowed.contains(ext.toLowerCase());
    }

    @PostMapping("/addComment")
    @Operation(summary = "添加评论")
    public JsonResult<Map> addComment(@RequestBody CommentAdd commentAdd, HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
        Comment comment = new Comment();
        comment.setCblog(commentAdd.getBlogId());
        comment.setComment(commentAdd.getComment());
        comment.setCuser(userId);
        Integer result = blogService.addComment(comment);
        if (result != null) {
            return new JsonResult<>(null);
        } else {
            return new JsonResult<>(null, ErrorCode.COMMENT_ADD_FAIL);
        }
    }

    @PostMapping("Comments")
    @Operation(summary = "评论列表")
    public JsonResult<JSONObject> Comments(@RequestParam Integer blogId) {
        JSONObject loginResponse = new JSONObject();
        List<CommentVo> commentList = blogService.getComment(blogId);
        if (commentList != null) {
            loginResponse.put("commentList", commentList);
            return new JsonResult<>(loginResponse);
        } else {
            return new JsonResult<>(null, ErrorCode.COMMENT_SHOW_FAIL);
        }
    }

    @PostMapping("/read")
    @Operation(summary = "阅读量")
    public JsonResult<JSONObject> read(@RequestParam Integer blogId) {
        JSONObject loginResponse = new JSONObject();
        Integer result = blogService.read(blogId);
        if (result != null) {
            loginResponse.put("result", result);
            return new JsonResult<>(loginResponse);
        } else {
            return new JsonResult<>(null);
        }
    }

}

